#include "serial.h"
#include "ui_serial.h"
#include <QDebug>
#include <QMessageBox>
#include <QTime>

static const char blankString[] = QT_TRANSLATE_NOOP("SettingsDialog", "N/A");

Serial::Serial(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Serial),
    m_isOpen(false),
    m_pSerialPort(new QSerialPort(this))
{
    ui->setupUi(this);
    serialInit();

    // 连接信号槽
    connect(ui->btnOpen, &QPushButton::clicked, this, &Serial::onOpenPort);
    connect(ui->btnStart, &QPushButton::clicked, this, [this](){
        if(m_isOpen) {
            m_pSerialPort->write(ui->textEdit->toPlainText().toUtf8());
        }
    });
}

Serial::~Serial()
{
    if(m_pSerialPort->isOpen()) {
        m_pSerialPort->close();
    }
    delete ui;
}

void Serial::serialInit()
{
    // 清空现有项
    ui->comboBoxPort->clear();

    // 获取可用串口
    const auto serialPortInfos = QSerialPortInfo::availablePorts();

    for(const auto &serialPortInfo : serialPortInfos){
        QStringList list;
        list << serialPortInfo.portName()
             << (!serialPortInfo.description().isEmpty() ? serialPortInfo.description() : blankString)
             << (!serialPortInfo.manufacturer().isEmpty() ? serialPortInfo.manufacturer() : blankString)
             << (!serialPortInfo.serialNumber().isEmpty() ? serialPortInfo.serialNumber() : blankString);

        ui->comboBoxPort->addItem(list.first(), list);
    }

    // 配置波特率
    ui->comboBoxBaudRate->addItem(QStringLiteral("9600"), QSerialPort::Baud9600);
    ui->comboBoxBaudRate->addItem(QStringLiteral("19200"), QSerialPort::Baud19200);
    ui->comboBoxBaudRate->addItem(QStringLiteral("38400"), QSerialPort::Baud38400);
    ui->comboBoxBaudRate->addItem(QStringLiteral("57600"), QSerialPort::Baud57600);
    ui->comboBoxBaudRate->addItem(QStringLiteral("115200"), QSerialPort::Baud115200);
    ui->comboBoxBaudRate->setCurrentIndex(4); // 默认115200

    // 数据位
    ui->comboBoxDatabits->addItem("5", QSerialPort::Data5);
    ui->comboBoxDatabits->addItem("6", QSerialPort::Data6);
    ui->comboBoxDatabits->addItem("7", QSerialPort::Data7);
    ui->comboBoxDatabits->addItem("8", QSerialPort::Data8);
    ui->comboBoxDatabits->setCurrentIndex(3); // 默认8

    // 校验位
    ui->comboBoxParity->addItem("NONE", QSerialPort::NoParity);
    ui->comboBoxParity->addItem("EVEN", QSerialPort::EvenParity);
    ui->comboBoxParity->addItem("ODD", QSerialPort::OddParity);
    ui->comboBoxParity->addItem("SPACE", QSerialPort::SpaceParity);
    ui->comboBoxParity->addItem("MARK", QSerialPort::MarkParity);

    // 停止位
    ui->comboBoxStopbit->addItem("1", QSerialPort::OneStop);
    ui->comboBoxStopbit->addItem("1.5", QSerialPort::OneAndHalfStop);
    ui->comboBoxStopbit->addItem("2", QSerialPort::TwoStop);

    // 流控制
    ui->comboBoxFlowctl->addItem("None", QSerialPort::NoFlowControl);
    ui->comboBoxFlowctl->addItem("Hardware", QSerialPort::HardwareControl);
    ui->comboBoxFlowctl->addItem("Software", QSerialPort::SoftwareControl);
}

void Serial::onOpenPort()
{
    if(!m_isOpen) {
        // 设置串口属性
        m_pSerialPort->setPortName(ui->comboBoxPort->currentText());

        // 使用itemData获取枚举值，而不是转换文本
        m_pSerialPort->setBaudRate(static_cast<QSerialPort::BaudRate>(
            ui->comboBoxBaudRate->currentData().toInt()));
        m_pSerialPort->setDataBits(static_cast<QSerialPort::DataBits>(
            ui->comboBoxDatabits->currentData().toInt()));
        m_pSerialPort->setParity(static_cast<QSerialPort::Parity>(
            ui->comboBoxParity->currentData().toInt()));
        m_pSerialPort->setStopBits(static_cast<QSerialPort::StopBits>(
            ui->comboBoxStopbit->currentData().toInt()));
        m_pSerialPort->setFlowControl(static_cast<QSerialPort::FlowControl>(
            ui->comboBoxFlowctl->currentData().toInt()));

        if(m_pSerialPort->open(QIODevice::ReadWrite)) {
            m_isOpen = true;
            ui->btnOpen->setText("关闭串口");

            // 禁用配置控件
            ui->comboBoxPort->setEnabled(false);
            ui->comboBoxBaudRate->setEnabled(false);
            ui->comboBoxDatabits->setEnabled(false);
            ui->comboBoxParity->setEnabled(false);
            ui->comboBoxStopbit->setEnabled(false);
            ui->comboBoxFlowctl->setEnabled(false);

            connect(m_pSerialPort, &QSerialPort::readyRead, this, &Serial::readData);
        } else {
            QMessageBox::critical(this, "错误", "无法打开串口!");
        }
    } else {
        m_pSerialPort->close();
        m_isOpen = false;
        ui->btnOpen->setText("打开串口");

        // 启用配置控件
        ui->comboBoxPort->setEnabled(true);
        ui->comboBoxBaudRate->setEnabled(true);
        ui->comboBoxDatabits->setEnabled(true);
        ui->comboBoxParity->setEnabled(true);
        ui->comboBoxStopbit->setEnabled(true);
        ui->comboBoxFlowctl->setEnabled(true);
    }
}

void Serial::readData()
{
    const QByteArray data = m_pSerialPort->readAll();
    if(!data.isEmpty()) {
        // 添加时间戳和换行
        QString text = QString("[%1] %2")
                          .arg(QTime::currentTime().toString("hh:mm:ss.zzz"))
                          .arg(QString(data));
        ui->recieveArea->append(text);
    }
}
